using System;
using System.Data;
using System.Data.Common;
using Universe.SimpleQueue;

namespace Universe.SimpleQueue
{
    public partial class SimpleQueue
    {

        public static readonly QueueStatistic LocalStat = new QueueStatistic();
        
        public interface IConnectionInfo
        {
            DbConnection Connection { get; }
            DbTransaction Transaction { get; }
        }

        public readonly Func<IConnectionInfo> ConnectionFactory;
        public int CommandTimeout { get; set; }

        private SimpleQueue()
        {
            CommandTimeout = 20;
        }

        public SimpleQueue(Func<IConnectionInfo> connectionFactory) : this()
        {
            ConnectionFactory = connectionFactory;
        }


        public void PurgeOldMessages(String queueName, long secondsOfGap)
        {

            var connectionInfo = ConnectionFactory();
            var con = connectionInfo.Connection;
            var tran = connectionInfo.Transaction;

            DumpConnection(con, tran);

            try
            {
                String sql = "Delete From SimpleQueue Where (QueueName = @queueName) And (CreatedAt < @at)";
                DateTime at = UniversalTime - TimeSpan.FromSeconds(secondsOfGap);
                var cmd = AdoHelper.BindParameters(con, tran, sql, new { queueName, at });
                using (cmd)
                    cmd.ExecuteNonQuery();

                if (tran != null) tran.Commit();
            }
            catch (Exception ex)
            {
                if (tran != null)
                    tran.Rollback();

                throw new InvalidOperationException("PurgeOldMessages() of the queue '" + queueName + "' failed", ex);
            }
            finally
            {
                DumpConnection(con, tran);
                con.Close();
            }

        }

        public void PurgeOldMessages(long secondsOfGap)
        {

            var connectionInfo = ConnectionFactory();
            var con = connectionInfo.Connection;
            var tran = connectionInfo.Transaction;

            DumpConnection(con, tran);

            try
            {
                const string sql = "Delete From SimpleQueue Where (CreatedAt < @at)";
                DateTime at = UniversalTime - TimeSpan.FromSeconds(secondsOfGap);
                var cmd = AdoHelper.BindParameters(con, tran, sql, new { at });
                using (cmd)
                    cmd.ExecuteNonQuery();

                if (tran != null) tran.Commit();
            }
            catch (Exception ex)
            {
                if (tran != null)
                    tran.Rollback();

                throw new InvalidOperationException("PurgeOldMessages() failed", ex);
            }
            finally
            {
                DumpConnection(con, tran);
                con.Close();
            }

        }

        private DateTime UniversalTime
        {
            get
            {
                return DateTime.Now.ToUniversalTime();
            }
        }

        void DumpConnection(DbConnection con, DbTransaction tran)
        {
/*
            var cmd = AdoHelper.BindParameters(con, tran, "Select cast(@@SPID as varchar) + ': ' + cast(@@TRANCOUNT as varchar)", new {});
            using (cmd)
            {
                Trace.WriteLine("SQL Connection: " + cmd.ExecuteScalar());
            }
*/
        }




    }
}